﻿using Bussiness.Interface;
using Common;
using Common.Model;
using DapperLambda;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Bussiness.Service
{
    public class BaseService : IBaseService
    {
        #region Identity
        protected DbContext Context = null;
        public BaseService() {
            Context = new DbContext().ConnectionString(StaticConstant.connStr, (DatabaseType)int.Parse(StaticConstant.databaseType));
        }
        #endregion Identity

        #region IQueryable
        /// <summary>
        /// 单表查询
        /// </summary>
        /// <returns>IQueryable类型集合</returns>
        public virtual Result<IEnumerable<T>> GetTable<T>() where T : class
        {
            Result<IEnumerable<T>> result = new Result<IEnumerable<T>>();
            result.Data = null;
            try
            {
                result.Data = Context.Select<T>().QueryMany();
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        #endregion

        #region===Select===
        /// <summary>
        /// 查找全部
        /// </summary>
        /// <returns></returns>
        public virtual Result<List<T>> Select<T>() where T : class
        {
            Result<List<T>> result = new Result<List<T>>();
            result.Data = new List<T>();
            try
            {
                result.Data = Context.Select<T>().QueryMany() as List<T>;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 根据条件查找
        /// </summary>
        /// <param name="expreesions">lambda表达式数组</param>
        /// <returns></returns>
        public virtual Result<List<T>> Select<T>(params Expression<Func<T, bool>>[] expreesions) where T : class
        {
            Result<List<T>> result = new Result<List<T>>();
            result.Data = new List<T>();
            try
            {
                SqlLamCommand<T> sqlCmd = Context.Select<T>();
                CustomWhereIn(ref sqlCmd, expreesions);
                result.Data = sqlCmd.QueryMany() as List<T>;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 根据条件查找
        /// </summary>
        /// <typeparam name="M"></typeparam>
        /// <param name="expression">lambda表达式1</param>
        /// <param name="expression2">lambda表达式2</param>
        /// <returns></returns>
        public virtual Result<List<T>> SelectWhereIn<T, M>(Expression<Func<T, object>> expression, Expression<Func<M, object>> expression2) where M : class
            where T : class
        {
            Result<List<T>> result = new Result<List<T>>();
            result.Data = new List<T>();
            try
            {
                SqlLamCommand<M> sqlCmdWhere = Context.Select<M>().Select(expression2);
                result.Data = Context.Select<T>().WhereIsIn(expression, sqlCmdWhere).QueryMany() as List<T>;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        #endregion

        #region ===SelectPage===
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageIndex">第几页</param>
        /// <param name="pageSize">每页记录数</param>
        /// <param name="recordCount">返回总记录数</param>
        /// <returns></returns>
        public virtual Result<List<T>> SelectPage<T>(int pageIndex, int pageSize, out int recordCount) where T : class
        {
            Result<List<T>> result = new Result<List<T>>();
            result.Data = new List<T>();
            recordCount = 0;
            try
            {
                result.Data = Context.Select<T>().QueryPage(pageIndex, pageSize, out recordCount) as List<T>;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 按条件进行分页查询
        /// </summary>
        /// <param name="pageIndex">第几页</param>
        /// <param name="pageSize">每页记录数</param>
        /// <param name="recordCount">返回总记录数</param>
        /// <param name="expreesions">lambda表达式数组</param>
        /// <returns></returns>
        public virtual Result<List<T>> SelectPage<T>(int pageIndex, int pageSize, out int recordCount, params Expression<Func<T, bool>>[] expreesions) where T : class
        {
            Result<List<T>> result = new Result<List<T>>();
            result.Data = new List<T>();
            recordCount = 0;
            try
            {
                SqlLamCommand<T> sqlCmd = Context.Select<T>();
                CustomWhereIn(ref sqlCmd, expreesions);
                result.Data = sqlCmd.QueryPage(pageIndex, pageSize, out recordCount) as List<T>;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        #endregion

        #region===QuerySingle===

        /// <summary>
        /// 按条件查找单个对象
        /// </summary>
        /// <param name="expreesions">lambda表达式数组</param>
        /// <returns></returns>
        public virtual Result<T> QuerySingle<T>(params Expression<Func<T, bool>>[] expreesions) where T : class
        {
            Result<T> result = new Result<T>();
            try
            {
                SqlLamCommand<T> sqlCmd = Context.Select<T>();
                CustomWhereIn(ref sqlCmd, expreesions);
                result.Data = sqlCmd.QuerySingle() as T;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        #endregion

        #region ===Insert===
        /// <summary>
        /// 通过实体进行插入数据
        /// </summary>
        /// <param name="enity">实体</param>
        /// <returns></returns>
        public virtual Result<bool> Insert<T>(T enity) where T : class
        {
            Result<bool> result = new Result<bool>();
            try
            {
                Context.Insert<T>(enity).Execute();
                result.Data = true;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        /// <summary>
        /// 返回自增主键ID
        /// </summary>
        /// <param name="enity">实体</param>
        /// <returns>返回自增主键ID</returns>
        public virtual Result<int> PrimaryKeyInsert<T>(T enity) where T : class
        {
            Result<int> result = new Result<int>();
            try
            {
                dynamic res = Context.Insert<T>(enity).Execute();
                result.Data = Convert.ToInt32(res);
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 批量插入实体集
        /// </summary>
        /// <param name="enitys">实体集</param>
        /// <returns></returns>
        public virtual Result<bool> MultiInsert<T>(IEnumerable<T> enitys) where T : class
        {
            Result<bool> result = new Result<bool>();
            try
            {
                Context.Insert<T>(enitys).Execute();
                result.Data = true;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        #endregion

        #region ===Update===
        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="enity">实体</param>
        /// <returns></returns>
        public virtual Result<bool> Update<T>(T enity) where T : class
        {
            Result<bool> result = new Result<bool>();
            try
            {
                Context.Update<T>(enity).Execute();
                result.Data = Context.Update<T>(enity).Execute();
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        /// <summary>
        /// 按条件更新实体
        /// </summary>
        /// <param name="enity">动态实体</param>
        /// <param name="expreesions">lambda表达式数组</param>
        /// <returns></returns>
        public virtual Result<bool> Update<T>(dynamic enity, params Expression<Func<T, bool>>[] expreesions) where T : class
        {
            Result<bool> result = new Result<bool>();
            try
            {
                UpdateSqlLamCommand<T> sqlCmd = Context.Update<T>();
                CustomWhereIn(ref sqlCmd, expreesions);
                result.Data = sqlCmd.Set(enity).Execute() > 0;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        #endregion

        #region ===Delete===
        /// <summary>
        /// 根据实体删除数据
        /// </summary>
        /// <param name="enity">实体</param>
        /// <returns></returns>
        public virtual Result<bool> Delete<T>(T enity) where T : class
        {
            Result<bool> result = new Result<bool>();
            try
            {
                result.Data = Context.Delete<T>(enity).Execute();
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        /// <summary>
        /// 按条件删除数据
        /// </summary>
        /// <param name="expreesions">lambda表达式数组</param>
        /// <returns></returns>
        public virtual Result<bool> Delete<T>(params Expression<Func<T, bool>>[] expreesions) where T : class
        {
            Result<bool> result = new Result<bool>();
            try
            {
                DeleteExpressionCommand<T> sqlCmd = Context.Delete<T>();
                CustomWhereIn(ref sqlCmd, expreesions);
                result.Data = (sqlCmd.Execute()) > 0;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        #endregion

        #region ======SelectSum
        public virtual Result<dynamic> SelectSum<T>(Expression<Func<T, object>> property, params Expression<Func<T, bool>>[] expressions) where T : class
        {
            Result<dynamic> result = new Result<dynamic>();
            try
            {
                SqlLamCommand<T> sqlCmd = Context.Select<T>().SelectSum(property);
                CustomWhereIn(ref sqlCmd, expressions);
                IDictionary<string, object> obj = sqlCmd.QueryDynamicSingle() as IDictionary<string, object>;
                result.Data = obj.Values.FirstOrDefault();
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        #endregion

        #region ===Exist===
        /// <summary>
        /// 判断是否存在
        /// </summary>
        /// <param name="expression">lambda表达式数组</param>
        /// <param name="expressions">lambda表达式数组</param>
        /// <returns></returns>
        public virtual Result<bool> Esxist<T>(Expression<Func<T, object>> expression, params Expression<Func<T, bool>>[] expressions) where T : class
        {
            Result<bool> result = new Result<bool>();
            try
            {
                SqlLamCommand<T> sqlCmd = Context.Select<T>().SelectCount(expression);
                CustomWhereIn(ref sqlCmd, expressions);
                IDictionary<string, object> obj = sqlCmd.QueryDynamicSingle() as IDictionary<string, object>;
                result.Data = Convert.ToInt32(obj.Values.FirstOrDefault()) > 0;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        #endregion

        #region ===selectCount==
        /// <summary>
        /// 查找总记录数
        /// </summary>
        /// <param name="expression">lambda表达式数组</param>
        /// <param name="expressions">lambda表达式数组</param>
        /// <returns></returns>
        public virtual Result<int> SelectCount<T>(Expression<Func<T, object>> expression, params Expression<Func<T, bool>>[] expressions) where T : class
        {
            Result<int> result = new Result<int>();
            try
            {
                SqlLamCommand<T> sqlCmd = Context.Select<T>().SelectCount(expression);
                CustomWhereIn(ref sqlCmd, expressions);
                IDictionary<string, object> res = sqlCmd.QueryDynamicSingle() as IDictionary<string, object>;
                result.Data = Convert.ToInt32(res.Values.FirstOrDefault());
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        #endregion

        #region ===SelectWhereIn===
        /// <summary>
        /// SelectWhereIn
        /// </summary>
        /// <param name="porperty">某一属性</param>
        /// <param name="param">此属性的值范围</param>
        /// <returns></returns>
        public virtual Result<List<T>> SelectWhereIn<T>(Expression<Func<T, object>> porperty, IEnumerable<object> param) where T : class
        {
            Result<List<T>> result = new Result<List<T>>();
            try
            {
                result.Data = Context.Select<T>().WhereIsIn(porperty, param).QueryMany() as List<T>;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// SelectWhereIn
        /// </summary>
        /// <param name="porperty">某一属性</param>
        /// <param name="param">此属性的值范围</param>
        /// <param name="expressions">where条件</param>
        /// <returns></returns>
        public virtual Result<List<T>> SelectWhereIn<T>(Expression<Func<T, object>> porperty, IEnumerable<object> param, params Expression<Func<T, bool>>[] expressions) where T : class
        {
            Result<List<T>> result = new Result<List<T>>();
            try
            {
                SqlLamCommand<T> sqlCmd = Context.Select<T>();
                foreach (Expression<Func<T, bool>> item in expressions)
                {
                    sqlCmd = sqlCmd.Where(item);
                }
                result.Data = sqlCmd.WhereIsIn(porperty, param).QueryMany() as List<T>;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
            }
            return result;
        }
        #endregion

        #region ===extend===
        /// <summary>
        /// SqlLamCommand
        /// </summary>
        /// <param name="sqlCmd">sqlCmd</param>
        /// <param name="expressions">lambda表达式数组</param>
        protected virtual void CustomWhereIn<T>(ref SqlLamCommand<T> sqlCmd, Expression<Func<T, bool>>[] expressions) where T : class
        {
            foreach (Expression<Func<T, bool>> item in expressions)
            {
                sqlCmd = sqlCmd.Where(item);
            }
        }

        /// <summary>
        /// UpdateSqlLamCommand
        /// </summary>
        /// <param name="sqlCmd">sqlCmd</param>
        /// <param name="expressions">lambda表达式数组</param>
        protected virtual void CustomWhereIn<T>(ref UpdateSqlLamCommand<T> sqlCmd, Expression<Func<T, bool>>[] expressions) where T : class
        {
            foreach (Expression<Func<T, bool>> item in expressions)
            {
                sqlCmd = sqlCmd.Where(item);
            }
        }
        /// <summary>
        /// DeleteExpressionCommand
        /// </summary>
        /// <param name="sqlCmd">sqlCmd</param>
        /// <param name="expressions">lambda表达式数组</param>
        protected virtual void CustomWhereIn<T>(ref DeleteExpressionCommand<T> sqlCmd, Expression<Func<T, bool>>[] expressions) where T : class
        {
            foreach (Expression<Func<T, bool>> item in expressions)
            {
                sqlCmd = sqlCmd.Where(item);
            }
        }
        #endregion

        #region 释放资源
        public virtual void Dispose()
        {
            if (this.Context != null)
            {
                this.Context.Dispose();
            }
        }
        #endregion
    }
}
